<template>
  <view style="display: flex">
    <slot name="header">
      <button size="mini" @click="open('in')">内部人员</button>
      <button size="mini" @click="open('out')">外部人员</button>
    </slot>
  </view>

  <uni-popup ref="userPopup" type="right" class="userPopup">
    <view class="popup-body">
      <view class="search" style="display: flex; justify-content: space-around">
        <text class="search-label"> 姓名： </text>
        <uni-easyinput
          @change="change"
          type="text"
          size="small"
          v-model="nickName"
          class="search-input"
          suffixIcon="search"
          @iconClick="search"
        />
      </view>
      <uni-table
        ref="table"
        border
        stripe
        type="selection"
        emptyText="暂无更多数据"
        @selection-change="selectionChange"
        class="data-table"
        :loading="loading"
      >
        <uni-tr>
          <uni-th width="50" align="center">姓名</uni-th>
          <uni-th width="100" v-if="apiType == 'in'" align="center"
            >部门</uni-th
          >
          <uni-th width="100" v-else align="center">证书编号</uni-th>
        </uni-tr>
        <uni-tr v-for="(item, index) in tableData" :key="index">
          <uni-td>{{ item.nickName || item.name }}</uni-td>
          <uni-td>
            <view class="name">{{
              item.dept?.deptName || item.certificateNumber || "无"
            }}</view>
          </uni-td>
        </uni-tr>
      </uni-table>
      <uni-pagination
        v-model="pageCurrent"
        :total="total"
        :pageSize="pageSize"
        :show-icon="true"
        @change="change"
      />
      <view class="" style="display: flex; justify-content: space-around">
        <button type="danger" size="mini" @click="cancel">取 消</button>
        <button type="primary" size="mini" @click="onSubmit">添 加</button>
      </view>
    </view>
  </uni-popup>
</template>

<script setup>
import { ref, defineProps, defineEmits, defineExpose, watch } from "vue";
import { listUser, lssgry } from "@/api/user.js";
const props = defineProps({
  modelValue: [String, Object, Array],
  names: {
    type: String,
    default: "",
  },
  // 数量限制
  limit: {
    type: Number,
    default: 1000,
  },
  userList: {
    type: Array,
    default: () => [],
  },
});
const emits = defineEmits(["update:modelValue", "change"]);

let tableData = ref([]);
let pageSize = ref(10);
let pageCurrent = ref(1);
let total = ref(0);
let loading = ref(false);
let disableSelectionChangeFlag = ref(false);
let isSubmitButtonDisabled = ref(true);
let tableIds = ref([]);
let tableNames = ref([]);
let selectItems = ref([]);
let removeIds = ref([]);
let preItems = ref([]);
let currentItems = ref([]);
const table = ref()

const userPopup = ref();
const apiType = ref("");
const open = (type) => {
  apiType.value = type;
  userPopup.value.open();
  init()
};

const nickName = ref(null);


async function search(res) {
  pageCurrent.value = 1;
  await getData(pageSize.value, pageCurrent.value);
  clearAndreSelect();
}

async function cancel() {
  nickName.name = '';
  pageCurrent.value = 1;
  await getData(pageSize.value, pageCurrent.value);
  clearAndreSelect();
  userPopup.value.close();
}

// 多选
function selectionChange(e) {
  if (!disableSelectionChangeFlag.value) {
    currentItems.value = e.detail.index;
    //新增项
    let addItem = currentItems.value.filter(item => !preItems.value.includes(item));
    for (let i = 0; i < addItem.length; i++) {
      let currentId = apiType.value === 'in' ? addItem[i].userId : addItem[i].id
      let findIndex = removeIds.value.findIndex(item => item === currentId)
      if (findIndex !== -1) {
        removeIds.value.splice(findIndex, 1)
      }
    }
    //删除项
    let removeItem = preItems.value.filter(item => !currentItems.value.includes(item));
    preItems.value = [...currentItems.value];
    if (addItem.length > 0) {
      addItem.forEach(i => {
        let personId = apiType.value === 'in' ? tableData.value[i].userId : tableData.value[i].id;
        if (!tableIds.value.includes(personId)) {
          tableIds.value.push(personId);
          tableNames.value.push(apiType.value === 'in' ? tableData.value[i].nickName : tableData.value[i].name);
          selectItems.value.push(tableData.value[i])
        }
      })
    }
    if (removeItem.length > 0) {
      removeItem.forEach(i => {
        let personId = apiType.value === 'in' ? tableData.value[i].userId : tableData.value[i].id;
        let personName = apiType.value === 'in' ? tableData.value[i].nickName : tableData.value[i].name;
        removeIds.value.push(personId);
        if (tableIds.value.includes(personId)) {
          tableIds.value = tableIds.value.filter(a => personId != a);
          tableNames.value = tableNames.value.filter(a => a != personName)
          selectItems.value = selectItems.value.filter(item => {
            if (apiType.value === 'in') {
              return item.userId !== personId
            } else if(apiType.value === 'out'){
              return item.id !== personId
            }
          })
        }
      })
    }
  }

}

// 分页组件触发
async function change(e) {
  disableSelectionChangeFlag.value = true;
  await getData(pageSize.value, e.current);
  clearAndreSelect();
  disableSelectionChangeFlag.value = false
  pageCurrent.value = e.current;
}

// 清空表单
function clearAndreSelect() {
  disableSelectionChangeFlag.value = true;
  table.value.clearSelection()
  preItems.value.length = 0;
  currentItems.value.length = 0;
  tableData.value.forEach(data => {
    if (tableIds.value.includes(apiType.value === 'in' ? data.userId : data.id)) {
      let index = tableData.value.indexOf(data);
      table.value.toggleRowSelection(index)
      preItems.value.push(index);
      currentItems.value.push(index);
    }
  })
  disableSelectionChangeFlag.value = false;
}

// 获取数据
function getData(pageSize, currentPage) {
  const api = apiType.value == "in" ? listUser : lssgry;
  const params = {
    pageSize,
    pageNum: currentPage
  }
  nickName.value && (params.nickName = params.name = nickName.value);
  return new Promise((resolve, reject) => {
    api(params).then((data) => {
      tableData.value = data.rows;
      total.value = data.total;
      pageCurrent.value = data.current;
      resolve();
    })
  })

}
// 初始化方法
const init = async () => {
  disableSelectionChangeFlag.value = true;
  await getData(pageSize.value, pageCurrent.value);
  if (props.userList.length) {
    // 根据内外部类型先做过滤一次
    const currentTypeList = props.userList.filter(item => item.type === apiType.value)
    tableIds.value = currentTypeList.map(item => item.id);
    tableNames.value = currentTypeList.map(item => item.name)
    selectItems.value = selectItems.value.filter(item => tableIds.value.includes(item.id))
  }
  clearAndreSelect();
  disableSelectionChangeFlag.value = false
}

watch(() => tableIds, (newValue) => {
  if (Object.keys(newValue.value).length > 0) {
    isSubmitButtonDisabled.value = false;
  } else {
    isSubmitButtonDisabled.value = true;
  }
}, {deep: true, immediate: true})

const onSubmit = () => {
  //跳转到异常填写界面
  if (tableIds.value.length > props.limit) {
    return uni.showToast({
      title: `最多选择${props.limit}人`,
    });
  }

  const ids = props.userList
    .filter((item) => item.type == apiType.value)
    .map((user) => user.id);
  const newData = selectItems.value
    .filter((item) => !ids.includes(apiType.value == "in" ? item.userId : item.id))
    .map((ele) => {
      return {
        name: apiType.value == "in" ? ele.nickName : ele.name,
        id: apiType.value == "in" ? ele.userId : ele.id,
        type: apiType.value,
        zsh: apiType.value == "in" ? ele.cardNumber : ele.certificateNumber,
      }
    });
  emits("change", {
    ids: tableIds.value.join(","),
    names: tableNames.value.join(","),
    list: newData,
    removeIds: removeIds.value,
    done: (names, userList) => {
      removeIds.value = []
      cancel();
    },
  });
};
</script>

<style lang="scss" scoped>
.input {
  height: 70upx;
  border: 1px solid #ccc;
  background-color: #fff;
  border-radius: 10upx;
  flex: 1;
}
.popup-body {
  height: 100%;
  background-color: #fff;
  max-width: 80vw;
  .data-table {
    height: calc(100vh - 300upx);
    overflow: auto;
  }
}

.search {
  height: 120upx;
  padding: 20upx;
  &-label {
    line-height: 80upx;
  }
}
</style>
